<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
<head>
<title>Renoise Actions</title>
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <link type="text/css" href="/css/default.css" media="screen" rel="stylesheet" />

    <!-- required scripts -->
    <script type="text/javascript" src="/js/jquery-1.5.1.min.js"></script>
    <script type="text/javascript" src="/js/jquery-ui-1.8.1.custom.min.js"></script>
    <script type="text/javascript" src="/fg-menu/fg.menu.js"></script>
    <script type="text/javascript" src="/js/cookies.js"></script>

    <!-- required styles -->
   <!--  <link type="text/css" href="/css/ui-lightness/jquery-ui-1.8.1.custom.css" media="screen" rel="stylesheet" /> -->
    <link type="text/css" href="/fg-menu/theme/ui.core.css" media="screen" rel="stylesheet" />
    <link type="text/css" href="/fg-menu/theme/ui.theme.css" media="screen" rel="stylesheet" />
    <link type="text/css" href="/fg-menu/fg.menu.css" media="screen" rel="stylesheet" />

    <!-- styles for this example page only -->
  <style type="text/css">
      body { background-color: #aaa; height: 100%;}
      #center { height: 100%;  font-size:62.5%; border: 10% solid #333; padding: 10px 20px 20px 20px; width: 600px; margin: 0px auto; background-color: white;  }
      .fg-menu-container  { font-size:62.5%; }
      #menuLog { font-size:1.4em; margin:10px 20px 20px; }
      .hidden { position:absolute; top:0; left:-9999px; width:1px; height:1px; overflow:hidden; }

      .fg-button { clear:left; margin:0 4px 40px 20px; padding: .4em 1em; text-decoration:none !important; cursor:pointer; position: relative; text-align: center; zoom: 1; }
      .fg-button .ui-icon { position: absolute; top: 50%; margin-top: -8px; left: 50%; margin-left: -8px; }
      a.fg-button { float:left;  }
      button.fg-button { width:auto; overflow:visible; } /* removes extra button width in IE */

      .fg-button-icon-left { padding-left: 2.1em; }
      .fg-button-icon-right { padding-right: 2.1em; }
      .fg-button-icon-left .ui-icon { right: auto; left: .2em; margin-left: 0; }
      .fg-button-icon-right .ui-icon { left: auto; right: .2em; margin-left: 0; }
      .fg-button-icon-solo { display:block; width:8px; text-indent: -9999px; }   /* solo icon buttons must have block properties for the text-indent to work */
    
      .fg-button.ui-state-loading .ui-icon { background: url(/fg-menu/spinner_bar.gif) no-repeat 0 0; }
     .ui-widget-header, .ui-widget-header a { color: white; }
    
     #droppable { width: 100px; height: 150px; padding: 0.5em; float: right; margin: 10px; }
     #rack { width: 300px; }
     .action_widget { height: 30px; border: 1px solid white; padding: 0.5em; margin: 3px;}
     .trashcan {  font-weight: bold; float: right; width: 10px; height: 10px; display: block;}
     .widget_elm { font-weight: bold; float: left}
     .clearfix { clear: both; }
  </style>

  <!-- style exceptions for IE 6 -->
  <!--[if IE]>
  <style type="text/css">
    .fg-menu-ipod .fg-menu li { width: 95%; }
    .fg-menu-ipod .ui-widget-content { border:0; }
  </style>
  <![endif]-->  
    
    <script type="text/javascript">
      var levels = 3;
      var dynamic = false;

      var path = new Array();
      var branch = null;
      var menu_tree = new Array();
      var address = "";
      
      var $rack;

      function merge(subtree, tree){
         tree[branch] = subtree
      }

      function get_action_type(name){
         return name.match(/\[(.+)\]/);
      }
      
      function get_action_name(name){
         return name.match(/(.+)(?=\[)/);
      }

      function save_rack(){
        var str = "";
        var $elms = $rack.filter(".action_widget");
        $elms.each(function(){str += $(this).text()});
        if ($elms.length > 0){
           alert(str);
        }
        //Store in Document API?
        //Or createCookie(); ?
      }

      function trash_action(elm){
        $(elm).parent().fadeOut(function(){ $(this).remove(); });
        return false;
      }

      // image deletion function
      var recycle_icon = '<a href="link/to/recycle/script/when/we/have/js/off" title="Recycle this image" class="ui-icon ui-icon-refresh">Recycle image</a>';
      function deleteImage($item) {
        $item.fadeOut(function() {
          var $list = $('ul',$trash).length ? $('ul',$trash) : $('<ul class="gallery ui-helper-reset"/>').appendTo($trash);

          $item.find('a.ui-icon-trash').remove();
          $item.append(recycle_icon).appendTo($list).fadeIn(function() {
            $item.animate({ width: '48px' }).find('img').animate({ height: '36px' });
          });
        });
      }

      // image recycle function
      var trash_icon = '<a href="link/to/trash/script/when/we/have/js/off" title="Delete this image" class="ui-icon ui-icon-trash">Delete image</a>';
      function recycleImage($item) {
        $item.fadeOut(function() {
          $item.find('a.ui-icon-refresh').remove();
          $item.append(trash_icon).find('img').css('height','72px').end().appendTo($gallery).fadeIn();
        });
      }
      
      $('#rack > li').click(function(ev) {
        var $item = $(this);
        var $target = $(ev.target);

        if ($target.is('a.ui-icon-trash')) {
          deleteImage($item);
        } else if ($target.is('a.ui-icon-zoomin')) {
          viewLargerImage($target);
        } else if ($target.is('a.ui-icon-refresh')) {
          recycleImage($item);
        }

        return false;
      });
      
    function get_options(path){
       var str = "<option>True</option><option>False</option>";
       var i = 0;
         while (i < 10){
            i++;
            str += "<option>"+i+"</option>";
         }
       return str;
      }

      function get_parent(path){
         var i = path.lastIndexOf("/");
         return path.substring(0,i);
      }

      var widgets = new Array();

      function register_action(path){
         widgets.push(path);
         return widgets.length - 1;
      }

      function create_action_widget(path, name){
         var type = get_action_type(name);
         var elm = "<a class='action_link' href='/"+ escape(path) + "'>"+name+"</a>";
         var bread = "<legend class='tiny'>"+get_parent(path)+"</legend>";

         var widget = "";
         if (type == null){
            widget = elm;
         } else if (type[0] == '[Trigger]') {
            widget = "<input type='submit' value='"+get_action_name(name)[0]+"' />";
         } else if (type[0] == '[Toggle]') {
            widget = "<input type='checkbox' /> " + get_action_name(name)[0];
         } else if (type[0] == '[Set]') {
            //Track XX
            //Execute on change?
            //Radio buttons for Booleans?
            widget = "<select>"+get_options(path)+"</select> <input type='submit' value='"+get_action_name(name)[0]+"' />";
            //widget = "<input type='text' /> " + get_action_name(name)[0];
         } else {
           widget = elm;
         }

         var w_id = register_action(path);

         var trashcan = "<a class='trashcan 0ui-icon 0ui-icon-trash' href='#' onclick='return trash_action(this);'>X</a>";
         $('#rack').append("<fieldset id='w_"+w_id+"' class='action_widget'>" + bread + "<span class='widget_elm'>" + widget + "</span>" + trashcan + "</fieldset>").fadeIn();
      }

      function getMenu(){
        // DYNAMIC MENU ITEMS
          $.post("actions.lua", {'path[]':path, full:dynamic, depth:levels}, function(subtree){
             //merge(subtree, menu_tree)

            $("#actions").html(subtree);
            $("#actions ul:first").attr('class','list_root');

            $('#hierarchybreadcrumb').menu({
              content : $("#actions").html(),
              backLink: false,
              callback: function(item){
                 branch = $(item).text();
                  path.push(branch);
                  address = ""
                  $('.fg-menu-crumb').each(function(){
                     address += $(this).text() + "/";
                  });
                  address += branch;
                  create_action_widget(address,branch);
                  if (dynamic){ getMenu(); }

               }
            });
          });
      }

      $(function(){
        $('body').prepend('<div id="gmenu"></div>');
        $('#gmenu').load('/menu.html');

         $rack = $('#rack');

         $rack.submit(function(){ return false; });

         // Continuously binding events
         $('.action_link').live('click',function(){
            var url = $(this).attr('href');
            $.post(url, {ajax:true});
            return false;
         });

         $('.widget_elm input').live('click',function(){
            var id = $(this).parents("fieldset").attr('id');
            var w_id = id.substring(2);
            var url = "/" + widgets[w_id];
            $.post(url, {ajax:true});
         });

         // MENU
         getMenu();

         // CONFIG
         if (!dynamic) { $('#config input[name="full"]').attr("checked", "checked"); }
         $('#config input[value=levels]').attr("checked", "checked");
         $('#levels').hide();

         $('#config input[name="full"]').click(function(){
            if ($(this).attr("checked")){
              $('#levels').hide();
            } else {
              $('#levels').show();
            }
            dynamic = $(this).attr("checked");
         });

         $('#config input[name="levels"]:checked').change(function(){
             levels = $(this).val();
         });
  
          // BUTTONS
          $('.fg-button').hover(
            function(){ $(this).removeClass('ui-state-default').addClass('ui-state-focus'); },
            function(){ $(this).removeClass('ui-state-focus').addClass('ui-state-default'); }
          );

      });
    </script>
    
</head>

<body>
 <div id="center">
  
  <h1>Renoise Actions Rack</h1>

  <p>The goal is to display a menu, initialized with only 1 level of items. As soon as the user clicks on an item, 
  the relevant branch is loaded and injected into the menu. Currently the server generates the tree as a HTML list,
  which makes injecting branches a bit hard/inefficient.</p>

   <p>TODO:</p>
  <ul>
   <li>Currently only TOGGLE type Actions work correctly</li>
   <li>For each Action, determine the valid range of values</li>
   <li>Bi-Directional communication: show feedback from Renoise</li>
   <li>Request branches instead of the whole catalog of Actions, and merge them in a local tree</li>
  </ul>


  <form id="config" action="#" style="color: #aaa; display: none;">
    <fieldset>
       <legend>Config</legend>
       <p id="full">Load the whole huge tree at once: <input type="checkbox" name="full" disabled="disabled" /></p>
       <p id="levels">Depth: 1<input type="radio" name="levels" value="1" /> 2 <input type="radio" name="levels" value="2" /> 3 <input type="radio" name="levels" value="3" /> 4 <input type="radio" name="levels" value="4" /></p>
     </fieldset>
  </form>

  <h2>The Menu</h2>
    <p>
      <a tabindex="0" href="#actions" class="fg-button fg-button-icon-right ui-widget ui-state-default ui-corner-all" id="hierarchybreadcrumb"><span class="ui-icon ui-icon-triangle-1-s"> </span>Actions Menu</a>
    </p>

    <div class='clearfix'></div>

    <form id="rack" class="ui-widget ui-widget-content ui-corner-all"><div class="fg-menu-breadcrumb ui-widget-header ui-corner-all ui-helper-clearfix fg-menu-header">Action Rack</div></form>
    <p><button class='ui-button ui-widget ui-corner-all ui-state-disabled' onclick="save_rack(); return false;">Save Action Rack</button></p>

   <div id="actions" class="hidden"></div>

 </div>
</body>
</html>
